package ec.linde.modulos.proyectos;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.primefaces.component.datatable.DataTable;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

import ec.linde.modulos.proyectos.servicio.ServicioRdo;
import ec.linde.modulos.proyectos.servicio.ServicioRegistroMaterial;
import ec.linde.persistencia.entidades.ProdConceptosMateriales;
import ec.linde.persistencia.entidades.proyectos.DetalleRdo;
import ec.linde.persistencia.entidades.proyectos.DetalleRegistroMaterial;
import ec.linde.persistencia.entidades.proyectos.Rdo;
import ec.linde.persistencia.entidades.proyectos.RegistroMaterial;

/**
 * TODO: Agregar descripcion
 * 
 * @FechaCreacion: 29/03/2013
 * @author: Alex Carrillo
 * @FechaModificacion: 29/03/2013
 * @author: Alex Carrillo
 * @version: 1.0
 */
@ManagedBean
@ViewScoped
public class RegistroMaterialContratistaBean extends PageController {

	private static final long serialVersionUID = 1L;

	/**
	 * Servicios
	 */
	@EJB
	private ServicioRegistroMaterial servicioRegistroMaterial;
	@EJB
	private ServicioRdo servicioRdo;

	/**
	 * Atributos Forma
	 */
	private RegistroMaterial registroMaterial;
	private DetalleRegistroMaterial detalleRegistroMaterialSeleccionado;
	private Rdo rdo;

	/**
	 * Listados 1. Lista Lazy DataModel 2. Lista Detalles 3. Listas Combo
	 */
	private LazyDataModel<Rdo> listaRdo;
	private List<DetalleRegistroMaterial> listaDetalleRegistroMaterial;
	/**
	 * UI
	 */
	private DataTable dtRdo;
	private DataTable dtDetalleRegistroMaterial;

	/**
	 * PostContrutor
	 */
	@PostConstruct
	public void init() {

		listaRdo = new LazyDataModel<Rdo>() {

			private static final long serialVersionUID = 1L;

			@Override
			public List<Rdo> load(int startIndex, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
				List<Rdo> lista = new ArrayList<Rdo>();

				boolean ordenar = sortOrder == SortOrder.ASCENDING ? true : false;
				lista = servicioRdo.obtenerListaPorPagina(startIndex, pageSize, sortField, ordenar, filters);

				listaRdo.setRowCount(servicioRdo.contarPorCriterio(filters));

				return lista;
			}
		};

	}

	/**
	 * Metodos
	 */

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#editar()
	 */
	public String editar() {
		addInfoMessage("Accion no permitida");
		return "";
	}

	/*
	 * (non-Javadoc)\
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#guardar()
	 */
	public String guardar() {
		try {
			if (validar()) {
				servicioRegistroMaterial.guardar(registroMaterial);
				addInfoMessage("Registro Guardado Correctamente");
				setEditado(false);
				limpiar();
				return "registroMaterialBodega.xhtml?faces-redirect=true";
			} else {
				return "";
			}
		} catch (Exception e) {
			addErrorMessage("Error al Guardar el registro");
		}
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#eliminar()
	 */
	public String eliminar() {
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.asinfo.as2.controller.PageControllerAS2#limpiar()
	 */
	@Override
	public String limpiar() {
		registroMaterial = null;
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see ec.linde.modulos.proyectos.PageController#cancelar()
	 */
	@Override
	public String cancelar() {
		setEditado(false);
		limpiar();
		return "registroMaterialBodega.xhtml?faces-redirect=true";
	}

	/**
	 * TODO: Agregar descripcion del metodo
	 * 
	 * @return
	 */
	public List<DetalleRegistroMaterial> getListaDetalleRegistroMaterial() {
		if (listaDetalleRegistroMaterial == null) {
			listaDetalleRegistroMaterial = new ArrayList<DetalleRegistroMaterial>();
			for (DetalleRegistroMaterial detalleRegistroMaterial : registroMaterial.getListaDetalleRegistroMaterial()) {
				if (!detalleRegistroMaterial.isEliminado()) {
					listaDetalleRegistroMaterial.add(detalleRegistroMaterial);
				}
			}
		}
		return listaDetalleRegistroMaterial;
	}

	/**
	 * Carga el plan operativo ya sea desde el proyecto o desde el ultimo plan operativo
	 */
	public void cargarRegistroMaterialDesdeRdo() {

		if (rdo != null && registroMaterial == null) {

			// Cargo el detalle del Plan Operativo Actual
			rdo = servicioRdo.cargarDetalleConMateriales(rdo.getId());

			// Cargo el plan operativo
			HashMap<String, String> filters = new HashMap<String, String>();
			filters.put("rdo.idRdo", "" + rdo.getId());
			List<RegistroMaterial> lista = servicioRegistroMaterial.obtenerListaCombo("", true, filters);

			// Si la lista del registroMaterial no existe me crea un nuevo registroMaterial
			if (lista.isEmpty()) {

				registroMaterial = new RegistroMaterial();
				registroMaterial.setRdo(rdo);
				registroMaterial.setFecha(new Date());
				for (DetalleRdo drdo : rdo.getListaDetalleRdo()) {
					for (ProdConceptosMateriales conceptoMaterial : drdo.getConcepto().getProdConceptosMaterialeses()) {
						DetalleRegistroMaterial dregistroMaterial = new DetalleRegistroMaterial();
						dregistroMaterial.setRegistroMaterial(registroMaterial);
						dregistroMaterial.setPartida(drdo.getPartida());
						dregistroMaterial.setConceptoMaterial(conceptoMaterial);
						dregistroMaterial.setCantidad((drdo.getCantidad().multiply(new BigDecimal(conceptoMaterial.getComaCantidad()))).setScale(2,
								RoundingMode.HALF_UP));
						registroMaterial.getListaDetalleRegistroMaterial().add(dregistroMaterial);
					}
				}

			} else {

				// Cargo el detalle del RegistroMaterial Actual y seto el plan operativo asl registroMaterial
				registroMaterial = servicioRegistroMaterial.cargarDetalle(lista.get(0).getId());
				registroMaterial.setRdo(rdo);

				// Se llena el hasmap de los detalles del registroMaterial actual y se eliminan
				HashMap<String, DetalleRegistroMaterial> hmDRegistroMaterial = new HashMap<String, DetalleRegistroMaterial>();
				for (DetalleRegistroMaterial detalleRegistroMaterial : registroMaterial.getListaDetalleRegistroMaterial()) {
					hmDRegistroMaterial.put(detalleRegistroMaterial.getPartida().getPadeId() + "~"
							+ detalleRegistroMaterial.getConceptoMaterial().getComaId(), detalleRegistroMaterial);
					detalleRegistroMaterial.setEliminado(true);
				}

				// Se recorre el detalle del plan operativo para habilitar los registros que estan en el plan operativo y dar el orden al
				// registroMaterial del plan
				// operativo
				for (DetalleRdo drdo : rdo.getListaDetalleRdo()) {

					// Verifica si existe el detalle del registroMaterial y si existe lo activa caso contrario lo crea
					for (ProdConceptosMateriales conceptoMaterial : drdo.getConcepto().getProdConceptosMaterialeses()) {
						DetalleRegistroMaterial detalleRegistroMaterial = hmDRegistroMaterial.get(drdo.getPartida().getPadeId() + "~"
								+ conceptoMaterial.getComaId());
						if (detalleRegistroMaterial != null) {
							detalleRegistroMaterial.setEliminado(false);
						} else {
							detalleRegistroMaterial = new DetalleRegistroMaterial();
							registroMaterial.getListaDetalleRegistroMaterial().add(detalleRegistroMaterial);
						}
						detalleRegistroMaterial.setRegistroMaterial(registroMaterial);
						detalleRegistroMaterial.setCantidad((drdo.getCantidad().multiply(new BigDecimal(conceptoMaterial.getComaCantidad())))
								.setScale(2, RoundingMode.HALF_UP));
						detalleRegistroMaterial.setPartida(drdo.getPartida());
						detalleRegistroMaterial.setConceptoMaterial(conceptoMaterial);
					}
				}

			}
			totalizar();
			setEditado(true);
		}

	}

	/**
	 * Aprueba el plan operativo
	 */
	public void aprobar() {
		// if (registroMaterial != null) {
		// if (registroMaterial.getEstado() == Estado.ELABORADO) {
		//
		// if (validarAprobacion(registroMaterial)) {
		// servicioRegistroMaterial.cambiarEstado(registroMaterial.getId(), Estado.APROBADO);
		// addInfoMessage("El registro se ha aprobado correctamente");
		// }
		//
		// } else {
		// addInfoMessage("Solo los planos operativos elaborados pueden ser aprobados");
		// }
		//
		// } else {
		// addInfoMessage("Seleccione un Registro");
		// }

	}

	// private boolean validarAprobacion(RegistroMaterial registroMaterial) {
	// return false;
	// }

	/**
	 * Totaliza los valores del plan operativo
	 */
	public void totalizar() {
		servicioRegistroMaterial.totalizar(registroMaterial);
	}

	/**
	 * VAlida el plan opertaivo antes de guardar
	 * 
	 * @return
	 */
	private boolean validar() {
		boolean resultado = true;
		return resultado;
	}

	/**
	 * Metodos Eventos
	 */

	/**
	 * Metodos GET Y SET
	 */

	/**
	 * Get del atributo registroMaterial
	 * 
	 * @return el valor del atributo registroMaterial
	 */
	public RegistroMaterial getRegistroMaterial() {
		return registroMaterial;
	}

	/**
	 * Set del atributo registroMaterial
	 * 
	 * @param proyecto
	 *            valor para asignar al atributo registroMaterial
	 */
	public void setRegistroMaterial(RegistroMaterial registroMaterial) {
		this.registroMaterial = registroMaterial;
	}

	public Rdo getRdo() {
		return rdo;
	}

	public void setRdo(Rdo rdo) {
		this.rdo = rdo;
	}

	public DetalleRegistroMaterial getDetalleRegistroMaterialSeleccionado() {
		return detalleRegistroMaterialSeleccionado;
	}

	public void setDetalleRegistroMaterialSeleccionado(DetalleRegistroMaterial detalleRegistroMaterialSeleccionado) {
		this.detalleRegistroMaterialSeleccionado = detalleRegistroMaterialSeleccionado;
	}

	public LazyDataModel<Rdo> getListaRdo() {
		return listaRdo;
	}

	public void setListaRdo(LazyDataModel<Rdo> listaRdo) {
		this.listaRdo = listaRdo;
	}

	public DataTable getDtRdo() {
		return dtRdo;
	}

	public void setDtRdo(DataTable dtRdo) {
		this.dtRdo = dtRdo;
	}

	/**
	 * Get del atributo dtDetalleRegistroMaterial
	 * 
	 * @return el valor del atributo dtDetalleRegistroMaterial
	 */
	public DataTable getDtDetalleRegistroMaterial() {
		return dtDetalleRegistroMaterial;
	}

	/**
	 * Set del atributo dtDetalleRegistroMaterial
	 * 
	 * @param dtDetalleRegistroMaterial
	 *            valor para asignar al atributo dtDetalleRegistroMaterial
	 */
	public void setDtDetalleRegistroMaterial(DataTable dtDetalleRegistroMaterial) {
		this.dtDetalleRegistroMaterial = dtDetalleRegistroMaterial;
	}

}
